// EORecord.cs
//
//  Copyright (C) 2008 Whitemice Consulting
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//

using System;
using System.Collections.Generic;

namespace Whitemice.EOMono
{
  public abstract class EORecord
  {
    private   Dictionary<EOFieldDef, IEOValue>  fields;
    protected EOEntity                          entity;
    protected IEOConnection                     connection;

    public EORecord(IEOConnection conn, EOEntity e)
    {
      connection = conn;
      entity = e;
      fields = new Dictionary<EOFieldDef, IEOValue>();
      foreach(EOFieldDef f in Entity.Fields)
      {
        fields.Add(f, EOValue.EOFieldValue(f.Name, this.Entity));
      }      
    } // end ctor
    
    public EOEntity Entity { get { return entity; } }
    
    public string EntityName { get { return entity.Name; } }
    
    protected EOFieldDef GetField(string name)
    {
      return Entity.GetField(name);
    }
    
    public bool HasField(string fieldName)
    {
      string name = fieldName.ToLower();
      foreach(EOFieldDef f in fields.Keys)
      {
        if ((f.Name.ToLower() == name) ||
            (f.Alias.ToLower() == name))
          return true;
      } // end foreach
      return false;
    } // end HasField
    
    public IEOValue this [string fieldName]
    {
      get { return Get(fieldName); }
      set { Set(fieldName, value); }
    }
    
    public IEOValue Get(string fieldName)
    {
      string n = fieldName.ToLower();
      foreach(EOFieldDef d in fields.Keys)
      {
        if ((d.Name.ToLower() == n) ||
            ((d.Alias != null) && (d.Alias.ToLower() == n)))
          return fields[d];
      } // end foreach
      throw new Exception(string.Format("No such field as {0}", fieldName));
    }
    
    public string KindOfField(string key)
    {
      EOFieldDef d = GetField(key);
      return d.Kind;
    }
    
    public IList<string> FieldNames
    { 
      get 
      { 
        return Entity.FieldNames; 
      } 
    }   
    
    public IList<EOFieldDef> Fields
    {
      get
      {
        return Entity.Fields;
      }
    }
    
    public void Set(string fieldName, object fieldValue)
    {
      IEOValue   v = fields[GetField(fieldName)];
      try
      {
        if (fieldValue is DBNull)
        {
          // field set to null
          v.IsNull = true;
          return;
        }
        if (v is EOSerial) 
        {
          // setting serial value (special case)
          int i = Convert.ToInt32(fieldValue);
          (v as EOSerial).SetInternalValue(i);
          return;
        }
        // setting value
        v.Value = fieldValue;
      } catch (Exception ex)
        {
          string msg;
          
          msg = string.Format("Exception setting field {0}:{1}({2}) to value \"{3}\" ({4}).", 
                              Entity.Name, fieldName, v.GetType(), fieldValue, fieldValue.GetType());
          EOManager.Log.Fatal(msg);
          throw new Exception(msg, ex);
        }
    } // end Set       
  }
}
